/**
 * 
 */
package TecMaster.Equipamentos;

import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Classe Equipamento do projeto TecMaster. Responsavel por guardar as
 * informacoes do equipamento.
 * 
 * @author Antonio Ricardo.
 * 
 */
public abstract class Equipamento implements Comparable<Equipamento>,
		Serializable {
	private static final long serialVersionUID = 2L;

	public enum MarcasAutorizadas {
		SONY, PHILIPS, LG, SAMSUNG
	}

	public enum DefeitosMaisComuns {
		NAO_LIGA, DESLIGA_APOS_LIGAR, SEM_SINAL_AUDIO, SEM_SINAL_VIDEO
	}

	public enum EstadoDoEquipamento {
		NA_FILA, NO_TECNICO, CONSERTADO, SEM_CONSERTO
	}

	private MarcasAutorizadas marca;
	private DefeitosMaisComuns defeito;
	private EstadoDoEquipamento estado;
	private Calendar dataDeChegada;
	private int codigo;
	private String numNotaFiscal;
	private boolean taNaGarantia;
	private Calendar dataDeSaida;
	private int diasParaConserto;

	/**
	 * Construtor default de equipamento.
	 * 
	 * @param marca
	 *            um enum com a marca do equipamento.
	 * @param defeito
	 *            um enum com o defeito do equipamento.
	 * @param numNotaFiscal
	 *            o numero da nota fiscal do equipamento.
	 * @param codigo
	 *            o codigo do equipamento.
	 * @param taNaGarantia
	 *            true se tah na garantia, false caso contrario.
	 * @param totalDeDiasNaFila
	 *            os dias para que esse equipamento chegue ao tecnico.
	 * @param diasParaConserto
	 *            o max de dias para o equipamento ser consertado,
	 * @throws Exception
	 */
	public Equipamento(MarcasAutorizadas marca, DefeitosMaisComuns defeito,
			String numNotaFiscal, int codigo, boolean taNaGarantia,
			int totalDeDiasNaFila, int diasParaConserto) throws Exception {
		if (numNotaFiscal == null || numNotaFiscal.equals(""))
			throw new Exception("Numero de Nota Fiscal Invalido");
		this.marca = marca;
		this.defeito = defeito;
		this.dataDeChegada = new GregorianCalendar();
		this.numNotaFiscal = numNotaFiscal;
		this.taNaGarantia = taNaGarantia;
		this.codigo = codigo;
		this.estado = EstadoDoEquipamento.NA_FILA;
		this.diasParaConserto = diasParaConserto;
		this.dataDeSaida = setDataDeSaida(totalDeDiasNaFila);
	}

	/**
	 * Retorna a marca do equipamento.
	 * 
	 * @return a marca do equipamento.
	 */
	public MarcasAutorizadas getMarca() {
		return this.marca;

	}

	/**
	 * Retorna o defeito do equipamento.
	 * 
	 * @return o defeito do equipamento.
	 */
	public DefeitosMaisComuns getDefeito() {
		return this.defeito;
	}

	/**
	 * Retorna a data de chegada do equipamento.
	 * 
	 * @return a data de chegada do equipamento.
	 */
	public Calendar getDataDeChegada() {
		return this.dataDeChegada;
	}

	/**
	 * Retorna o numero da nota fiscal do equipamento.
	 * 
	 * @return o numero da nota fiscal do equipamento.
	 */
	public String getNumNotaFiscal() {
		return this.numNotaFiscal;
	}

	/**
	 * Retorna true se o equipamento tah na garantia, false caso contrario.
	 * 
	 * @return true se o equipamento tah na garantia, false caso contrario.
	 */
	public boolean isGarantia() {
		return this.taNaGarantia;
	}

	/**
	 * Retorna o estado do equipamento.
	 * 
	 * @return o estado do equipamento.
	 */
	public EstadoDoEquipamento getEstado() {
		return estado;
	}

	/**
	 * Altera o estado do equipamento.
	 * 
	 * @param estado
	 *            o novo estado do equipamento;
	 * 
	 */
	public void setEstado(EstadoDoEquipamento estado) {
		this.estado = estado;
	}

	/**
	 * Calcula a data de saida do equipamento
	 * 
	 * @param numDias
	 *            o numero de dias do equipamento na fila
	 * @return a data de saida do equipamento
	 */
	private Calendar setDataDeSaida(int numDias) {
		Calendar data = new GregorianCalendar();
		data.add(Calendar.DAY_OF_YEAR, +(numDias + getDiasParaConserto()));
		return data;
	}

	/**
	 * Retorna a data de saida do Equipamento
	 * 
	 * @return a data de saida do equipamento
	 */
	public Calendar getDataDeSaida() {
		return dataDeSaida;
	}

	/**
	 * Retorna o codigo do Equipamento
	 * 
	 * @return o codigo do Equipamento
	 */
	public String getCodigo() {
		return String.format("%06d", codigo);
	}

	/**
	 * Retorna os dias para o concerto do Equipamento
	 * 
	 * @return os dias para o concerto do Equipamento
	 */
	public int getDiasParaConserto() {
		return diasParaConserto;
	}

	/**
	 * Retorna Uma String referente ao estado da garantia
	 * 
	 * @return "Sim" se esta na garantia e "Nao" caso o contrario
	 */
	public String stringGarantia() {
		if (isGarantia())
			return "Sim";
		return "Nao";
	}

	/**
	 * Equals de Equipamento, compara o codigo de dois equipamentos
	 */
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Equipamento))
			return false;
		Equipamento equip = (Equipamento) obj;
		return getCodigo().equals(equip.getCodigo());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int compareTo(Equipamento o) {
		return getDataDeSaida().compareTo(o.getDataDeSaida());
	}

	/**
	 * Compara dois aparelhos pegando a marca e o defeito desse aparelho
	 * 
	 * @param e
	 *            o equipamento a ser comparado
	 * @return true se os equipamentos sao iguais
	 */
	public boolean comparaAparelhos(Equipamento e) {
		if (e.getClass().equals(this.getClass())) {
			if (this.getMarca().equals(e.getMarca())) {
				if (this.getDefeito().equals(e.getDefeito())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Imprime as informacoes do equipamento.
	 */
	public abstract String toString();

}
